#ifndef THREADPOOL_H
#define THREADPOOL_H
#include<pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
#include<exception>
#include <pthread.h>
#include <list>
#include"locker.h"
//locker和threadpool都是为了线程同步和有序处理请求T
template<typename T>//T是请求的任务
class threadpool{
private:
    int max_thread;//线程池中的线程总数
    int max_job;//工作队列的最大总数
    pthread_t *m_threads;//线程池数组
    std::list<T*>m_workqueue;
    mutex m_queuelocker;//如果有上锁了，说明工作队列增加或减小分配任务，则有关的队列任务的不用动。
    sem m_queuestat;//信号量来判断是否有任务处理

    bool m_stop;//是否结束线程，true表示线程全部释放
private:
static void* work(void * arg);//创建线程时work函数是静态的函数,不能访问非静态.
//所以创建进程时通过第四个参数传递本类非静态对象
void run();//run表明线程池启动起来了，当一个线程运行起来了，就要执行run
public:
    threadpool(int thread_number = 8, int max_requests = 10000);
    ~threadpool();
    bool append(T* request);//为工作队列增加工作
};
template< typename T >
threadpool< T >::threadpool(int thread_number, int max_requests) : 
        max_thread(thread_number), max_job(max_requests), 
        m_stop(false), m_threads(NULL) {

    if((thread_number <= 0) || (max_requests <= 0) ) {
        throw std::exception();
    }

    m_threads = new pthread_t[max_thread];
    if(!m_threads) {
        throw std::exception();
    }

    // 创建thread_number 个线程，并将他们设置为脱离线程。
    for ( int i = 0; i < thread_number; ++i ) {
        printf( "create the %dth thread\n", i);
        if(pthread_create(m_threads + i, NULL, work, this ) != 0) {
            delete [] m_threads;
            throw std::exception();
        }
        
        if( pthread_detach( m_threads[i] ) ) {
            delete [] m_threads;
            throw std::exception();
        }
    }
}

template<typename T>
threadpool<T>::~threadpool(){
    delete [] m_threads;
    m_stop=true;
}
template<typename T>
bool threadpool<T>::append(T* request){
    m_queuelocker.lock();
    if(m_workqueue.size()>max_job){
        m_queuelocker.unlock();
        return false;
    }
    m_workqueue.push_back(request);
    m_queuelocker.unlock();
    m_queuestat.post();
    return true;
}
template<typename T>
void* threadpool<T>::work(void * arg){
    threadpool * pool=(threadpool*) arg;
    pool->run();
    return pool;
}
template<typename T>
void threadpool<T>::run(){
    while (!m_stop)//不true就一直运行
    {
        m_queuestat.wait();//等待有信号量加一，在append函数中信号量加一
        m_queuelocker.lock();
        if(m_workqueue.size()==0){
           continue;
        }
        T* request=m_workqueue.front();
        m_workqueue.pop_front();
        m_queuelocker.unlock();
        //到此获取到了队首任务并且完成

        if(!request){
            continue;
        }
        request->process();//process是任务类真正的执行函数
    }
}
#endif